import java.util.HashSet;
import java.util.Random;
import java.util.Set;

/**
 * 加减法口算练习系统测试类
 * 用于对系统功能进行模块化测试
 */
public class CalculationSystemTest {
    
    public static void main(String[] args) {
        System.out.println("========== 加减法口算练习系统功能测试 ==========");
        
        // 执行各项测试
        testRandomNumberGeneration();
        testAdditionExerciseGeneration();
        testSubtractionExerciseGeneration();
        testUniqueExerciseGeneration();
        testExerciseDistribution();
        
        // 显示综合测试数据集
        displayTestDataSet();
        
        System.out.println("\n========== 测试完成 ==========");
    }
    
    /**
     * 测试1：随机数生成功能
     * 验证生成的随机数是否在指定范围内
     */
    public static void testRandomNumberGeneration() {
        System.out.println("\n1. 随机数生成功能测试");
        System.out.println("----------------------------------------");
        System.out.println("测试编号 | 测试描述 | 预期结果 | 实际结果 | 测试结果");
        System.out.println("---------|----------|----------|----------|----------");
        
        Random random = new Random();
        boolean allTestsPassed = true;
        
        // 测试1.1：生成0-100之间的随机数
        int testCount1 = 1000;
        boolean test1Passed = true;
        for (int i = 0; i < testCount1; i++) {
            int num = random.nextInt(101);
            if (num < 0 || num > 100) {
                test1Passed = false;
                break;
            }
        }
        allTestsPassed &= test1Passed;
        System.out.printf("T1.1     | 0-100随机数 | 0<=num<=100 | %s | %s\n",
                test1Passed ? "符合范围" : "超出范围", test1Passed ? "通过" : "失败");
        
        // 测试1.2：生成0-50之间的随机数
        int testCount2 = 1000;
        boolean test2Passed = true;
        for (int i = 0; i < testCount2; i++) {
            int num = random.nextInt(51);
            if (num < 0 || num > 50) {
                test2Passed = false;
                break;
            }
        }
        allTestsPassed &= test2Passed;
        System.out.printf("T1.2     | 0-50随机数  | 0<=num<=50  | %s | %s\n",
                test2Passed ? "符合范围" : "超出范围", test2Passed ? "通过" : "失败");
        
        System.out.println("\n结论：随机数生成功能测试 " + (allTestsPassed ? "通过" : "失败"));
    }
    
    /**
     * 测试2：加法算式生成功能
     * 验证加法算式是否满足和不超过100的要求
     */
    public static void testAdditionExerciseGeneration() {
        System.out.println("\n2. 加法算式生成功能测试");
        System.out.println("----------------------------------------");
        System.out.println("测试编号 | 测试描述 | 预期结果 | 实际结果 | 测试结果");
        System.out.println("---------|----------|----------|----------|----------");
        
        Random random = new Random();
        boolean allTestsPassed = true;
        
        // 测试2.1：验证加法结果不超过100
        int testCount = 1000;
        int maxSum = 0;
        boolean test1Passed = true;
        
        for (int i = 0; i < testCount; i++) {
            int a = random.nextInt(100);
            int b = random.nextInt(101 - a);
            int sum = a + b;
            maxSum = Math.max(maxSum, sum);
            
            if (sum > 100) {
                test1Passed = false;
                break;
            }
        }
        allTestsPassed &= test1Passed;
        System.out.printf("T2.1     | 加法结果限制 | 和<=100 | 最大和=%d | %s\n",
                maxSum, test1Passed ? "通过" : "失败");
        
        System.out.println("\n结论：加法算式生成功能测试 " + (allTestsPassed ? "通过" : "失败"));
    }
    
    /**
     * 测试3：减法算式生成功能
     * 验证减法算式是否满足差不小于0的要求
     */
    public static void testSubtractionExerciseGeneration() {
        System.out.println("\n3. 减法算式生成功能测试");
        System.out.println("----------------------------------------");
        System.out.println("测试编号 | 测试描述 | 预期结果 | 实际结果 | 测试结果");
        System.out.println("---------|----------|----------|----------|----------");
        
        Random random = new Random();
        boolean allTestsPassed = true;
        
        // 测试3.1：验证减法结果不小于0
        int testCount = 1000;
        int minDiff = Integer.MAX_VALUE;
        boolean test1Passed = true;
        
        for (int i = 0; i < testCount; i++) {
            int a = random.nextInt(100) + 1;
            int b = random.nextInt(a + 1);
            int diff = a - b;
            minDiff = Math.min(minDiff, diff);
            
            if (diff < 0) {
                test1Passed = false;
                break;
            }
        }
        allTestsPassed &= test1Passed;
        System.out.printf("T3.1     | 减法结果限制 | 差>=0   | 最小差=%d | %s\n",
                minDiff, test1Passed ? "通过" : "失败");
        
        System.out.println("\n结论：减法算式生成功能测试 " + (allTestsPassed ? "通过" : "失败"));
    }
    
    /**
     * 测试4：不重复算式生成功能
     * 验证生成的算式是否完全不重复
     */
    public static void testUniqueExerciseGeneration() {
        System.out.println("\n4. 不重复算式生成功能测试");
        System.out.println("----------------------------------------");
        System.out.println("测试编号 | 测试描述 | 预期结果 | 实际结果 | 测试结果");
        System.out.println("---------|----------|----------|----------|----------");
        
        boolean allTestsPassed = true;
        
        // 测试4.1：验证哈希集合去重功能
        Set<String> exercises = new HashSet<>();
        
        // 正确添加考虑交换律的加法算式
        int a1 = 1, b1 = 2;
        String add1 = a1 <= b1 ? "ADD:" + a1 + ":" + b1 : "ADD:" + b1 + ":" + a1;
        exercises.add(add1);
        
        int a2 = 2, b2 = 1;
        String add2 = a2 <= b2 ? "ADD:" + a2 + ":" + b2 : "ADD:" + b2 + ":" + a2;
        exercises.add(add2); // 这应该不会增加集合大小，因为和add1相同
        
        exercises.add("SUB:5:3");
        exercises.add("SUB:3:5"); // 减法不视为重复
        
        boolean test1Passed = (exercises.size() == 3); // 应该只有3个唯一元素
        allTestsPassed &= test1Passed;
        System.out.printf("T4.1     | 哈希集合去重 | 正确去重 | 唯一元素数=%d | %s\n",
                exercises.size(), test1Passed ? "通过" : "失败");
        
        // 测试4.2：模拟小规模无重复生成
        Set<String> smallExercises = new HashSet<>();
        boolean hasDuplicate = false;
        int generated = 0;
        int maxAttempts = 1000; // 防止无限循环
        int attempts = 0;
        
        while (generated < 20 && attempts++ < maxAttempts) {
            Random random = new Random();
            boolean isAddition = random.nextBoolean();
            String canonicalForm;
            
            if (isAddition) {
                int a = random.nextInt(20);
                int b = random.nextInt(21 - a);
                if (a <= b) {
                    canonicalForm = "ADD:" + a + ":" + b;
                } else {
                    canonicalForm = "ADD:" + b + ":" + a;
                }
            } else {
                int a = random.nextInt(20) + 1;
                int b = random.nextInt(a + 1);
                canonicalForm = "SUB:" + a + ":" + b;
            }
            
            if (smallExercises.add(canonicalForm)) {
                generated++;
            }
        }
        
        boolean test2Passed = (generated == 20);
        allTestsPassed &= test2Passed;
        System.out.printf("T4.2     | 小规模生成测试 | 生成20个 | 成功生成%d个 | %s\n",
                generated, test2Passed ? "通过" : "失败");
        
        System.out.println("\n结论：不重复算式生成功能测试 " + (allTestsPassed ? "通过" : "失败"));
    }
    
    /**
     * 测试5：加减法比例分配测试
     * 验证加减法算式的比例是否合理
     */
    public static void testExerciseDistribution() {
        System.out.println("\n5. 加减法比例分配测试");
        System.out.println("----------------------------------------");
        System.out.println("测试编号 | 测试描述 | 预期结果 | 实际结果 | 测试结果");
        System.out.println("---------|----------|----------|----------|----------");
        
        Random random = new Random();
        boolean allTestsPassed = true;
        
        // 测试5.1：验证加减法比例合理性（各至少25%）
        int testCount = 100;
        int additionCount = 0;
        int subtractionCount = 0;
        final int minEachType = testCount / 4;
        
        // 模拟v0.3的分配逻辑
        while (additionCount + subtractionCount < testCount) {
            boolean isAddition;
            if (additionCount < minEachType) {
                isAddition = true;
            } else if (subtractionCount < minEachType) {
                isAddition = false;
            } else {
                isAddition = random.nextBoolean();
            }
            
            if (isAddition) {
                additionCount++;
            } else {
                subtractionCount++;
            }
        }
        
        boolean additionTestPassed = additionCount >= minEachType;
        boolean subtractionTestPassed = subtractionCount >= minEachType;
        allTestsPassed &= additionTestPassed && subtractionTestPassed;
        
        System.out.printf("T5.1     | 加法比例     | >=25%%    | %.1f%%    | %s\n",
                (double)additionCount / testCount * 100, additionTestPassed ? "通过" : "失败");
        System.out.printf("T5.1     | 减法比例     | >=25%%    | %.1f%%    | %s\n",
                (double)subtractionCount / testCount * 100, subtractionTestPassed ? "通过" : "失败");
        
        System.out.println("\n结论：加减法比例分配测试 " + (allTestsPassed ? "通过" : "失败"));
    }
    
    /**
     * 综合测试数据集
     * 包含各种边界情况和典型情况的测试用例
     */
    public static void displayTestDataSet() {
        System.out.println("\n========== 综合测试数据集 ==========");
        System.out.println("测试用例编号 | 算式类型 | 操作数1 | 操作数2 | 预期结果 | 验证要点");
        System.out.println("------------|---------|--------|--------|---------|----------");
        System.out.println("TC01        | 加法     | 0      | 0      | 0       | 零加零边界");
        System.out.println("TC02        | 加法     | 99     | 1      | 100     | 和为100边界");
        System.out.println("TC03        | 加法     | 50     | 50     | 100     | 相等数相加");
        System.out.println("TC04        | 加法     | 10     | 20     | 30      | 正常加法");
        System.out.println("TC05        | 减法     | 0      | 0      | 0       | 零减零边界");
        System.out.println("TC06        | 减法     | 100    | 0      | 100     | 减零边界");
        System.out.println("TC07        | 减法     | 100    | 100    | 0       | 相等数相减边界");
        System.out.println("TC08        | 减法     | 50     | 25     | 25      | 正常减法");
        System.out.println("TC09        | 加法重复 | 5      | 3      | 8       | 加法交换律检测");
        System.out.println("TC10        | 减法重复 | 8      | 5      | 3       | 减法非交换律检测");
    }
}